CQCIS.workflow.Line = function(config) {
    Ext.apply(this, config);
    this.elListeners = this.listeners;
    delete this.listeners;
    CQCIS.workflow.Line.superclass.constructor.call(this);
    this.init();
};

Ext.extend(CQCIS.workflow.Line, Ext.util.Observable, {
    id: null,
    name: 'New Line',
    number: -1,
    type: 'line',
    shape: 'polyline',
    property: null,
    selected: false,
    fromX: -1,
    fromY: -1,
    toX: -1,
    toY: -1,
    polyDot: [],
    textFlag: false,
    mirrorFlag: false,
    obj: null,
    strokeObj: null,
    textObj: null,
    fromNode: null,
    toNode: null,
    points: '0,0 10,10',
    strokecolor: '#ff9f15',
    strokeweight: '1',
    rendered: false,
    render: Ext.emptyFn,
    getEl: function() {
        return Ext.fly(this.obj);
    },
    init: function() {
        if (this.rendered === false) {
            var obj = document.createElement('v:polyline');
            obj.strokecolor = this.strokecolor;
            obj.strokeweight = this.strokeweight;
            obj.style.position = 'absolute';
            obj.style.zIndex = this.mirrorFlag ? '1500' : '2';
            obj.style.cursor = 'pointer';
            
            var strokeObj = document.createElement('v:stroke');
            obj.appendChild(strokeObj);
            strokeObj.endArrow = "Classic";
            this.strokeObj = strokeObj;
            
            if (this.textFlag) {
                var textObj = document.createElement('v:textbox');
                textObj.inset = '5px,5px,5px,5px';
                textObj.innerHTML = this.name;
                this.obj.title = this.name;
                Ext.apply(textObj.style, {
                    textAlign: 'center',
                    lineHeight: '20pt',
                    color: this.textcolor
                });
                obj.appendChild(textObj);
                this.textObj = textObj;
            }
            
            this.obj = obj;
            
            this.ownerCt.paletteEl.dom.appendChild(this.obj);
            //this.obj.points.value = this.points;
            
            if (!this.mirrorFlag) {
                this.number = this.ownerCt.lines.length + 1;
                if (this.id === null) {
                    this.id = 'line_' + this.number;
                }
                this.obj.id = this.id;
                this.ownerCt.lines.push(this);
            }
            
            if (this.elListeners) {
                Ext.fly(this.obj).on(Ext.apply(this.elListeners, {
                    scope: this
                }));
                delete this.elListeners;
            }
            
            if (this.fromNodeId) {
                this.fromNode = this.ownerCt.findNode(this.fromNodeId);
            }
            
            if (this.toNodeId) {
                this.toNode = this.ownerCt.findNode(this.toNodeId);
            }
            
            if (this.fromNode && this.toNode) {
                this.relink();
                
                this.fromNode.toId.push(this.toNode.id);
                this.toNode.fromId.push(this.fromNode.id);
            }
            
            this.rendered = true;
        }
    },
    setFrom: function(x, y, obj) {
        this.fromX = this.ownerCt.getX(x);
        this.fromY = this.ownerCt.getY(y);
        if (obj) {
            this.fromNode = obj;
        }
        this.polyDot = [];
        this.obj.points.value = this.getPointsValue();
    },
    setTo: function(x, y, obj) {
        this.toX = this.ownerCt.getX(x);
        this.toY = this.ownerCt.getY(y);
        if (obj) {
            this.toNode = obj;
        }
        this.polyDot = [];
        this.obj.points.value = this.getPointsValue();
    },
    setDisplay: function(flag) {
        this.obj.style.display = flag;
    },
    link: function(lineMirror) {
        this.fromNode = lineMirror.fromNode;
        this.fromNodeId = lineMirror.fromNode.id;
        this.toNode = lineMirror.toNode;
        this.toNodeId = lineMirror.toNode.id;
        
        this.fromNode.toId.push(this.toNodeId);
        this.toNode.fromId.push(this.fromNodeId);
        
        this.relink();
        this.fromNode.clearSelected();
    },
    relink: function() {
        var fromDots = this.fromNode.getDots();
        var toDots = this.toNode.getDots();
        this.relinkPolyline(fromDots, toDots);
    },
    relinkPolyline: function(fromDots, toDots) {
        this.polyDot = [];
        var fromFlag = 'a', toFlag = 'b';
        var fromPositioning = fromDots.e;
        var toPositioning = toDots.e;
        
        if (fromPositioning.x < toPositioning.x - 50) {
            if (fromPositioning.y > toPositioning.y + 50) {
                fromFlag = 'b';
                toFlag = 'c';
            } else if (fromPositioning.y < toPositioning.y - 50) {
                fromFlag = 'b';
                toFlag = 'd';
            } else {
                fromFlag = 'b';
                toFlag = 'a';
            }
        } else if (fromPositioning.x > toPositioning.x + 50) {
            if (fromPositioning.y > toPositioning.y + 50) {
                fromFlag = 'a';
                toFlag = 'c';
            } else if (fromPositioning.y < toPositioning.y - 50) {
                fromFlag = 'a';
                toFlag = 'd';
            } else {
                fromFlag = 'a';
                toFlag = 'b';
            }
        } else {
            if (fromPositioning.y > toPositioning.y + 50) {
                fromFlag = 'd';
                toFlag = 'c';
            } else if (fromPositioning.y < toPositioning.y - 50) {
                fromFlag = 'c';
                toFlag = 'd';
            } else {
                fromFlag = 'b';
                toFlag = 'b';
            }
        }
        
        this.fromX = fromDots[fromFlag].x;
        this.fromY = fromDots[fromFlag].y;
        this.toX = toDots[toFlag].x;
        this.toY = toDots[toFlag].y;
        if (!this.obj.points) {
            this.obj.points = {};
        }
        this.obj.points.value = this.getPointsValue();
    },
    getPointsValue: function() {
        var res = this.fromX + 'px,' + this.fromY + 'px';
        for (var i = 0; i < this.polyDot.length; i++) {
            res += ' ' + this.polyDot[i].x + 'px,' + this.polyDot[i].y + 'px';
        }
        res += ' ' + this.toX + 'px,' + this.toY + 'px';
        return res;
    },
    pointInObj: function(x, y) {
        var res = false;
        x = this.ownerCt.getX(x);
        y = this.ownerCt.getY(y);
        var x1 = this.fromX;
        var y1 = this.fromY;
        var x2 = this.toX;
        var y2 = this.toY;
        var x21 = x2 - x1;
        var y21 = y2 - y1;
        
        for (var i = 0; i < this.polyDot.length; i++) {
            x2 = this.polyDot[i].x;
            y2 = this.polyDot[i].y;
            x21 = x2 - x1;
            y21 = y2 - y1;
            if (x21 === 0) {
                res = (Math.abs(x - x1) < 5) && (Math.min(y1, y2) <= y) && (Math.max(y1, y2) >= y);
            } else if (y21 === 0) {
                res = (Math.abs(y - y1) < 5) && (Math.min(x1, x2) <= x) && (Math.max(x1, x2) >= x);
            }
            if (res) {
                break;
            }
            x1 = x2;
            y1 = y2;
        }
        if (!res) {
            x2 = this.toX;
            y2 = this.toY;
            x21 = x2 - x1;
            y21 = y2 - y1;
            if (x21 === 0) {
                res = (Math.abs(x - x1) < 5) && (Math.min(y1, y2) <= y) && (Math.max(y1, y2) >= y);
            } else if (y21 === 0) {
                res = (Math.abs(y - y1) < 5) && (Math.min(x1, x2) <= x) && (Math.max(x1, x2) >= x);
            } else {
                res = (Math.min(y1, y2) <= y) && (Math.max(y1, y2) >= y) && (Math.min(x1, x2) <= x) && (Math.max(x1, x2) >= x) && ((Math.abs(Math.floor((x21 / y21) * (y - y1) + x1 - x)) < 5) || (Math.abs(Math.floor((y21 / x21) * (x - x1) + y1 - y)) < 5));
            }
        }
        
        return res;
    },
    pointInStroke: function(x, y) {
        var res = -1;
        x = this.ownerCt.getX(x);
        y = this.ownerCt.getY(y);
        var x1 = this.fromX;
        var x2 = this.toX;
        var y1 = this.fromY;
        var y2 = this.toY;
        if ((Math.abs(x2 - x) < 6) && (Math.abs(y2 - y) < 6)) {
            res = 0;
        }
        if ((Math.abs(x1 - x) < 6) && (Math.abs(y1 - y) < 6)) {
            res = 1;
        }
        return res;
    },
    setSelected: function() {
        this.obj.strokecolor = '#ffeb8c';
        if (this.textObj) {
            this.textObj.style.color = '#ffeb8c';
        }
        this.selected = true;
        this.obj.style.zIndex = '22';
    },
    setMoveSelected: function() {
        this.obj.strokecolor = 'red';
        if (this.textObj) {
            this.textObj.style.color = 'green';
        }
        this.selected = true;
        this.obj.style.zIndex = '22';
    },
    clearSelected: function() {
        this.obj.strokecolor = '#ff9f15';
        if (this.textObj) {
            this.textObj.style.color = '#ff9f15';
        }
        this.selected = false;
        this.obj.style.zIndex = '2';
    },
    remove: function() {
        this.fromNode.toId.remove(this.toNode.id);
        this.toNode.fromId.remove(this.fromNode.id);
        Ext.fly(this.obj).removeAllListeners();
        this.obj.innerHTML = '';
        this.ownerCt.paletteEl.dom.removeChild(this.obj);
    },
    setText: function(text) {
        if (this.textFlag) {
            this.name = text;
            this.textObj.innerHTML = this.name;
        }
    }
});

CQCIS.workflow.Line.prototype.toString = function() {
    return '连线 ' + (this.textFlag ? ' ' + this.name : '') + '(' + this.fromX + ', ' + this.fromY + ' ' + this.toX + ', ' + this.toY + ')';
};
